
#include "../common.h"

#ifndef isCONVOLUtiONDefined
#define isCONVOLUtiONDefined
namespace xege {
	// 卷积器的命名空间
	// 必须先设置卷积核
	// 然后再进行计算
	namespace convoluation {
		// 图片宽高，
		int W, H, w, h, w2, h2;
		color_t* srcPixels;
		double*  core;
		bool flagIfSetCore = true;

		// 设置卷积核
		void setCore (unsigned int w, unsigned int h, double* sCore);
		// 初始化一个默认核
		void init (void);
		// 计算这个像素对应的卷积和结果
		color_t calcP (unsigned int x, unsigned int y);
		// 卷积
		void copyImage (IMAGE* pic);
		void calc (IMAGE* pic);

		void gksi (int r) {
			int R = 2*r+1;
			double *s = new double [R*R];
			for (int a = -r, b; a <= r; a ++) {
				for (b = -r; b <= r; b ++) {
					s [b*R+a] = GaussianWeight (a, b);
				}
			}
			setCore (R, R, s);
			// GaussianWeight ()
		}
		// 初始化一个默认核
		void init (void) {
			double s [9] {0.05, 0.05, 0.05, 0.05, 0.60, 0.05, 0.05, 0.05, 0.05};
			setCore (3, 3, s);
		}

		double R, G, B, A, v;
		color_t C;
		// 计算这个像素对应的卷积和结果
		color_t calcP (unsigned int x, unsigned int y) {
			R = 0.0; G = 0.0; B = 0.0; A = 0.0;
			for (unsigned  a = x - w2, b; a <= x + w2; a ++) {
				// SDL_Log ("????");
				// 草她奶奶的
				// for (b = y - h2; y < y + h2; b ++) {
				// 不小心写成了上面的样子，调试的时候出现的是文件打不开的问题，一直没发现这里的问题，草
				for (b = y - h2; b <= y + h2; b ++) {
					// SDL_Log ("x:%d, y:%d\t", (a-x+w2), (b-(y-h2)));
					// SDL_Log ("x:%d, y:%d\n", a, b);
					v = core [(b-(y-h2))*w + (a-x+w2)];
					C = srcPixels [b*W + a];
					R = v * XEGEGET_R (C);
					G = v * XEGEGET_G (C);
					B = v * XEGEGET_B (C);
					A = v * XEGEGET_A (C);
					// SDL_Log ("pixel:%lf", core [(b-(y-h2))*w + (a-x+w2)]);
					// SDL_Log ("pixel:%ld", srcPixels [b*W + a]);
					// SDL_Log ("%x", XEGERGBA (R, G, B, A));
				}
			}
			return XEGERGBA (R, G, B, A);
		}

		void calc (IMAGE* pic) {

			for (int x = w2, y; x <= W-w2; x++) {
				for (y = h2; y <= H-h2; y++) {
					// 绘制卷积结果到图片上
					
					pic -> drawPixel (x, y, calcP (x, y));
				}
			}
			// SDL_Log ("?");
		}

		// 复制图像
		void copyImage (IMAGE* pic) {

			if (flagIfSetCore) {
				SDL_Log ("your didn't have set the core");
			}

			// 获取图片宽高
			W = pic -> getWidth (), H = pic -> getHeight ();
			// 计算图片所需大小
			unsigned long s = W*H;
			// 申请所需空间
			// SDL_Log ("W:%d H:%d s:%ld",W, H, s);
			srcPixels = new color_t [s];
			// 获取图片像素信息指针
			// SDL_Log ("%x\n", pic -> getSurface ());
			const color_t* temp = (color_t*)(pic -> getSurface () -> pixels);
			// 复制图片
			while (s--) { srcPixels [s] = temp [s]; }
			// for (int a = 0, b; a < W; a ++) {
			// 	for (b = 0; b < H; b ++) {
			// 		*(srcPixels+b*W+a) = pic -> getP (a, b); 
			// 	}
			// }
		}

		// 设置卷积核
		void setCore (unsigned int w, unsigned int h, double* sCore) {
			// 只接受奇数宽高
			if ((!w&1) || (!h&1)) {
				SDL_Log ("sCore's W or H is not fit to the program, please check out document");
				exit (1);
			}
			if (sCore == nullptr) {
				SDL_Log ("sCore is empty, can't be used");
				exit (1);
			}
			unsigned long long int s = w * h;
			// 卷积核半轴
			w2 = w/2, h2 = h/2;
			convoluation::w = w;
			convoluation::h = h;
			// 申请卷积核空间
			core = new double [s];
			// 复制卷积核
			while (s--) { core [s] = *(sCore+s); }
			// 已有卷积核
			flagIfSetCore = false;
		}
	}  //  命名空间 convoluation 结尾
}  // 命名空间 xege 结尾
#endif